//
// Created by wxd on 2025/8/17.
//

#pragma once

#ifndef GRIDPLANE_H
#define GRIDPLANE_H

#include "Plane.h"
#include <memory>
#include "glm/glm.hpp"
#include "../glFramework/texture/Texture.h"
#include "../glFramework/shader/Shader.h"

// 网格生成算法
enum class GridGenType : uint8_t  {
    MOD = 0,
    XOR = 1,
    SMOOTH_XOR = 2,
};

class GridPlane {
public:
    GridPlane() {}

    // 交替颜色网格
    GridPlane(float w, float h, float size, glm::vec3 normal, glm::vec3 center, glm::vec3 colorA, glm::vec3 colorB, GridGenType type = GridGenType::MOD)
        : m_GridWidth(w), m_GridHeight(h), m_GridWSize(size), m_GridHSize(size), m_Normal(normal), m_Center(center),
          m_GridGenType(type), m_ColorA(colorA), m_ColorB(colorB) {
        m_Plane = std::make_unique<Plane>(m_GridWidth, m_GridHeight, m_Normal, m_Center);

        m_EnableAlternateGrid = true;
        m_EnableGridTexture = false;
    }

    // 交替纹理网格
    GridPlane(float w, float h, float size, glm::vec3 normal, glm::vec3 center,
        std::unique_ptr<Texture> textureA, std::unique_ptr<Texture> textureB, GridGenType type) :
        m_GridWidth(w), m_GridHeight(h), m_GridWSize(size), m_GridHSize(size),
        m_Normal(normal), m_Center(center), m_GridGenType(type) {

        m_PlaneTextureA = std::move(textureA);
        m_PlaneTextureB = std::move(textureB);

        m_EnableAlternateGrid = false;
        m_EnableGridTexture = true;
    }

    void setGridWidth(float w);
    void setGridHeight(float h);
    void setGridSize(float wsize, float hsize);
    void setGridCenter(glm::vec3 center);
    void setGridNormal(glm::vec3 normal);
    void setGridAlternateColor(glm::vec3 colorA, glm::vec3 colorB);
    void setGridAlternateTexture(std::unique_ptr<Texture> textureA, std::unique_ptr<Texture> textureB);
    void setEnableAlternateGrid(bool enable);
    void setEnableAlternateTexGrid(bool enable);
    void setGridGenType(GridGenType type);
    void setShader(const std::string& vertexPath, const std::string& fragmentPath);
    void setGridAmbient(float ambient);

    Shader& getShader() const;
    Plane& getPlane() const;
    glm::vec4 getGridScale() const;
    glm::vec3 getGridNormal() const;
    glm::vec3 getGridCenter() const;

    void setGridGenTypeUniform() const;
    void setGridAmbientUniform() const;
    void setGridScaleUniform() const;
    void setGridColorAUniform() const;
    void setGridColorBUniform() const;
    void setGridMvpMatrix(const glm::mat4& model, const glm::mat4& view, const glm::mat4& proj) const;

    void draw(const glm::mat4& model, const glm::mat4& view, const glm::mat4& proj);
    void destroy() const;

private:
    float m_GridWidth  { 0.f };                                     // 网格的宽高，单个网格的size，网格平面的几何中心
    float m_GridHeight { 0.f };
    float m_GridWSize   { 0.f };
    float m_GridHSize   { 0.f };
    glm::vec3 m_Normal { glm::vec3(0.f, 1.f, 0.f) };          // 网格外法 (外法的y分量记录的就是平面在OpenGL坐标系中的y轴位置)
    glm::vec3 m_Center { glm::vec3(0.f) };
    std::unique_ptr<Plane> m_Plane {};                              // 原始的网格平面对象

    GridGenType m_GridGenType { GridGenType::MOD };                 // 生成网格的算法类型，不同的类型对应的效果和性能都不一样

    glm::vec3 m_ColorA { glm::vec3(0.f) };                    // 交替网格的两种颜色
    glm::vec3 m_ColorB { glm::vec3(0.f) };
    std::unique_ptr<Texture> m_PlaneTextureA {};                    // 交替纹理
    std::unique_ptr<Texture> m_PlaneTextureB {};

    bool m_EnableGridTexture             { false };         // 是否支持网格纹理
    bool m_EnableAlternateGrid           { true  };         // 是否支持交替颜色网格
    bool m_EnableLodGrid                 { false };         // 是否支持Lod动态距离网格，开启后会额外消消耗GPU性能

    std::unique_ptr<Shader> m_GridShader {};                // 网格平面的着色器

    float m_GridAmbient { 1.f };                            // 调节平面的环境光系数

    int getGridType() const;

    // 着色器uniform类型变量
    const std::string uGridGenType = "uGridGenType";
    const std::string uGridAmbient = "uGridAmbient";
    const std::string uGridScale = "uGridScale";
    const std::string uGridColorA = "uGridColorA";
    const std::string uGridColorB = "uGridColorB";
};


#endif //GRIDPLANE_H
